﻿Imports Microsoft.VisualBasic

Public Enum EFormat
    EPUB
    MOBI
    SMASH
    PRINT
    HTML
End Enum

Public Class CKindle

#Region "Members"
    Private m_format As EFormat
    Private m_main As CTemplate
    Private m_contentsIntro As CTemplate
    Private m_contentsChapter As CTemplate
    Private m_externalLink As CTemplate
    Private m_image As CTemplate
    Private m_transcript As CTemplate
    Private m_notesAsText As CTemplate
    Private m_backToContents As CTemplate
    Private m_avContainer As CTemplate
    Private m_avItem As CTemplate
    Private m_linkToSet As CTemplate
    Private m_googlead As CTemplate

    Private m_isInspRead As Boolean
    Private m_isAllSermons As Boolean

    Public IsPagedHtml As Boolean = False
#End Region

#Region "Constructor"
    Public Sub New(ByVal format As EFormat)
        m_format = format
        Dim virtualPath As String = String.Concat("~/App_data/", format, "/")
        Dim folderPath As String = HttpContext.Current.Server.MapPath(virtualPath)

        m_main = New CTemplate("main.htm", folderPath)
        m_contentsIntro = New CTemplate("contents_intro.htm", folderPath)
        m_contentsChapter = New CTemplate("contents_chapter.htm", folderPath)
        m_externalLink = New CTemplate("external_link.htm", folderPath)
        m_image = New CTemplate("image.htm", folderPath)
        m_transcript = New CTemplate("transcript.htm", folderPath)
        m_notesAsText = New CTemplate("notesAsText.htm", folderPath)
        m_backToContents = New CTemplate("backToContents.htm", folderPath)
        m_avContainer = New CTemplate("av_container.htm", folderPath)
        m_avItem = New CTemplate("av_item.htm", folderPath)
        m_linkToSet = New CTemplate("link_to_set.htm", folderPath)
        Try
            m_googlead = New CTemplate("googlead.htm", folderPath)
        Catch
            m_googlead = New CTemplate()
        End Try
    End Sub
#End Region

#Region "Public"
    Public Function Display() As String 'Special case #1 - all sermons
        Dim list As CProductList = CProduct.Cache.Active.HavingTranscripts.SortByCreatedName
        Dim title As String = "Inspirational Readings"
        Dim url As String = "http://mikeconnellministries.com/transcripts.aspx"
        m_isAllSermons = True
        Return Main(list, title, url)
    End Function
    Public Shared INSP_READ As New List(Of Integer)({159, 220, 144, 887, 953, 1019, 1083, 1080, 939, 315, 209, 204, 206, 217, 1174, 1175, 240, 243, 184, 182, 171, 208, 287, 289, 288, 723, 697, 698, 740, 748, 754, 1079, 1161, 1165, 1166, 1167, 1371})
    Public Function InspirationalReadings() As String 'Special case #2 - hardcoded
        Dim list As CProductList = CProduct.Cache.GetByIds(INSP_READ)
        Dim title As String = "Inspirational Readings"
        Dim url As String = "http://mikeconnellministries.com/sermons.aspx?search=4103035"
        m_isInspRead = True
        Return Main(list, title, url)
    End Function

    Public Function Display(ByVal productId As Integer) As String
        Return Display(CProduct.Cache.GetById(productId))
    End Function
    Public Function Display(ByVal p As CProduct) As String
        If IsNothing(p) Then Return Me.Display 'Special case - all sermons

        If p.HasParent Then Return Display(p.BelongsTo) 'Always show the whole set

        Dim name As String = HttpUtility.HtmlEncode(p.ProductName)
        If Not String.IsNullOrEmpty(p.ProductNameChineseSimplified) Then
            name = String.Concat(name, "<br/>", p.ProductNameChineseSimplified)
        End If
        If Not String.IsNullOrEmpty(p.ProductNameChineseTraditional) AndAlso p.ProductNameChineseTraditional <> p.ProductNameChineseSimplified Then
            name = String.Concat(name, "<br/>", p.ProductNameChineseTraditional)
        End If

        If p.Children.Count > 0 Then 'Normal case - conference set
            Return Main(p.Children, name, CConfig.WebsiteUrl_Product(p))
        Else 'Special case - single, standalone sermon
            Dim standalone As New CProductList(1)
            standalone.Add(p)
            Return Main(standalone, name, CConfig.WebsiteUrl_Product(p))
        End If
    End Function
    Public Function Display(ByVal productIds As List(Of Integer)) As String
        Dim list As CProductList = CProduct.Cache.GetByIds(productIds).SortByCreatedName
        Dim title As String = TitleFor(list)
        Return Main(list, title, CConfig.WebsiteUrl)
    End Function
#End Region

#Region "Private - Generate from templates"
    Public Shared REPLACE As String() = {"Prelude", "Review", "Introduction", "Message", "Main Message", "Closing Prayer", "Activation", "Demonstration"}

    Public Shared Function EncodeAndReplace(s As String) As String
        Return ReplaceNewLines(HttpUtility.HtmlEncode(s))
    End Function
    Public Shared Function ReplaceNewLines(s As String) As String
        For Each i As String In REPLACE
            s = s.Replace(String.Concat("[", i, "]"), String.Concat("<b>", i, "</b>"))
        Next
        Return s.Replace(vbCrLf, "<br/>")
    End Function

    Private Function Main(ByVal list As CProductList, ByVal title As String, ByVal url As String) As String
        With m_main
            .Replace("title", title)
            .Replace("urlEncodedUrl", HttpUtility.UrlEncode(url))
            .Replace("links", Contents_Intro(list, True))
            If m_isInspRead Then
                Dim sb As New StringBuilder
                Transcriptions(sb, list)
                .Replace("articles", sb.ToString)
            Else
                .Replace("articles", Transcriptions(list.ByConferenceSet))
            End If
            If list.Count > 0 Then
                Dim p As CProduct = list(0)
                .Replace("SpeakerName", p.SpeakerNames)

                If p.HasParent Then p = p.BelongsTo
                .Replace("urlTranscript", CConfig.WebsiteUrl_TranscriptPaged(p))
                .Replace("keywords", p.ProductKeywords)
                .Replace("description", p.ProductDescription)
            Else
                .Replace("SpeakerName", "Pastor Mike Connell")
                .Replace("urlTranscript", "http://mikeconnellministries.com/ebooks.aspx")
            End If
            For Each i As String In REPLACE
                .ReplaceRaw(String.Concat("[", i, "]"), String.Concat("<b>", i, "</b>"))
            Next
            Return .Template '.Replace("[Prelude]", "<b>Prelude</b>").Replace("[Review]", "<b>Review</b>").Replace("[Introduction]", "<b>Introduction</b>").Replace("[Message]", "<b>Message</b>").Replace("[Main Message]", "<b>Main Message</b>").Replace("[Closing Prayer]", "<b>Closing Prayer</b>")
        End With
    End Function

    Public Function Contents_Intro(ByVal list As CProductList, ByVal nameAndDescription As Boolean, Optional simp As Boolean = False, Optional trad As Boolean = False) As String
        'Never happens?
        If list.Count = 0 Then Return String.Empty

        'Single sermon - None; or Bookmarks to Text/Notes plus external links to Audio/Video/Donate
        If list.Count = 1 Then Return Contents_Intro(list(0))

        'Sermon Set - Links to each transcript (and notes)
        If list.BelongsTo.Count = 1 Then
            Dim p As CProduct = list.BelongsTo(0)
            With m_contentsIntro
                Dim name As String = p.ProductName 'String.Concat(p.ProductName, " (", CUtilities.CountSummary(p.Children.HavingTranscripts, "sermon"), ")")
                If p.ProductSpeakerId <> ESpeaker.MikeConnell AndAlso (m_isAllSermons OrElse m_isInspRead OrElse m_format = EFormat.HTML) Then
                    name = String.Concat(name, " (", p.SpeakerName, ")")
                End If
                name = HttpUtility.HtmlEncode(name)

                .Reset()
                If m_isInspRead Then
                    .Replace("setName", String.Empty)
                    .Replace("description", String.Empty)
                    .Replace("other", String.Empty)
                    .Replace("setImage", "cover.jpg")
                End If
                If Not String.IsNullOrEmpty(p.ProductNameChineseSimplified) Then name = String.Concat(name, "<br/> &nbsp; ", p.ProductNameChineseSimplified)
                If Not String.IsNullOrEmpty(p.ProductNameChineseTraditional) AndAlso p.ProductNameChineseSimplified <> p.ProductNameChineseTraditional Then name = String.Concat(name, "<br/>  &nbsp; ", p.ProductNameChineseTraditional)
                .Replace("setName", name)
                .Replace("productId", p.ProductId)
                .Replace("setImage", p.ProductImage) ' CConfig.WebsiteUrl_ProductThumb(p))
                If nameAndDescription Then
                    Dim desc As String = HttpUtility.HtmlEncode(p.ProductDescription).Replace(vbCrLf, "<br/>")
                    If Not String.IsNullOrEmpty(p.ProductDescriptionChineseSimplified) Then desc = String.Concat(desc, "</span></p><p class=chinese><span>", p.ProductDescriptionChineseSimplified.Replace(vbCrLf, "<br/>"), "</span></p>")
                    If Not String.IsNullOrEmpty(p.ProductDescriptionChineseTraditional) Then desc = String.Concat(desc, "</span></p><p class=chinese><span>", p.ProductDescriptionChineseTraditional.Replace(vbCrLf, "<br/>"), "</span></p>")
                    .Replace("description", desc)
                Else
                    .Replace("description", String.Empty)
                End If
                .Replace("links", Contents_Chapters(list))

                .Replace("other", AudioVideoLinks(p))

                Return .Template
            End With
        End If

        'Many Sets, plus standalone
        Dim sb As New StringBuilder

        'Standalone Last
        With m_contentsIntro
            If list.StandAlone.Count > 0 Then
                .Reset()
                .Replace("setName", String.Empty) '"Sunday Sermons")
                .Replace("description", String.Empty)
                .Replace("productId", 0)

                Dim standAlone As CProductList = list.StandAlone ' New CProductList(list.StandAlone.HavingTranscripts)
                If m_isInspRead Then standAlone = list

                Dim sb2 As New StringBuilder
                If Not m_isInspRead Then sb2.Append(Contents_LinksToSets(list.BelongsTo))
                If standAlone.Count > 1 Then sb2.Append("<h1 style=""color:black"">Sunday Sermons</h1>")
                sb2.Append(Contents_Chapters(standAlone))

                .Replace("links", sb2.ToString)
                .Replace("other", String.Empty)
                sb.Append(.Template)
            End If
        End With

        ''Call self for each set
        'For Each p As CProduct In list.BelongsTo
        '    sb.Append(Contents_Intro(p.Children.HavingTranscripts, True))
        'Next

        Return sb.ToString
    End Function
    Public Function Contents_Intro(ByVal p As CProduct) As String 'Special case: Single sermon
        Return String.Empty 'todo: Bookmarks to Text/Notes plus external links to Audio/Video/Donate
    End Function

    Private Function AudioVideoLinks(ByVal p As CProduct) As String
        Dim sb As New StringBuilder

        If p.Children.Manuals.Count > 0 Then
            sb.Append(ManualLinks(p.Children.Manuals(0)))
        End If

        If p.HasBook Then
            sb.Append(PaperbackLink(p))
        End If

        If m_format <> EFormat.PRINT Then
            'Audio links no good for print
            If p.Children.HavingMp3.Count > 0 Then
                sb.Append(AudioVideoLinks("Audio", p.Children.HavingMp3, True, Nothing))
            End If

            sb.Append(NotesLinks(p))
        End If

        If p.Children.HavingVideos.Count > 0 Then
            If p.Children.HavingOnYouTube.Count > 0 Then
                sb.Append(AudioVideoLinks("YouTube", p.Children.HavingOnYouTube, False, True))
            End If

            If p.Children.HavingOnVimeo.Count > 0 Then
                sb.Append(AudioVideoLinks("Vimeo", p.Children.HavingOnVimeo, False, False))
            End If
        End If

        Return sb.ToString
    End Function
    Private Function AudioVideoLinks(ByVal hname As String, ByVal products As CProductList, ByVal isAudio As Boolean, ByVal isYouTube As Boolean?) As String
        Dim sb As New StringBuilder
        With m_avItem
            If Not isAudio AndAlso products.BelongsTo.Count = 1 Then
                Dim p As CProduct = products.BelongsTo(0)
                If isYouTube Then
                    If Not String.IsNullOrEmpty(p.ProductYouTubePlaylistId) Then
                        .Reset()
                        .Replace("name", "<b>YouTube Playlist &raquo;</b>")
                        .Replace("url", p.VideoUrl_YouTubePlaylist)
                        sb.Append(.Template)
                    End If
                Else
                    If Not String.IsNullOrEmpty(p.ProductVimeoChannelId) Then
                        .Reset()
                        .Replace("name", "<b>Vimeo Channel &raquo;</b>")
                        .Replace("url", p.VideoUrl_VimeoChannel)
                        sb.Append(.Template)
                    End If
                End If
            End If
            For Each i As CProduct In products
                .Reset()
                Dim pname As String = HttpUtility.HtmlEncode(i.ProductName)
                If m_format = EFormat.SMASH Then pname = hname & ": " & pname

                If isAudio Then
                    .Replace("name", pname & ".mp3")
                    .Replace("url", CConfig.Mp3(i))
                Else
                    .Replace("name", pname & ".mp4")
                    If isYouTube.HasValue Then
                        If isYouTube Then
                            .Replace("url", i.VideoUrl_YouTube)
                        Else
                            .Replace("url", i.VideoUrl_Vimeo)
                        End If
                    End If
                    .Replace("url", i.VideoUrl)
                End If
                sb.Append(.Template)
            Next
        End With

        With m_avContainer
            .Reset()
            .Replace("name", hname)
            .Replace("items", sb.ToString)
            Return .Template
        End With
    End Function
    Private Function PaperbackLink(ByVal p As CProduct) As String
        Dim sb As New StringBuilder
        With m_avItem
            .Reset()
            If p.HasBook2 OrElse p.HasBook3 Then
                If p.HasBook Then
                    .Replace("name", "Createspace(1)")
                    .Replace("url", CConfig.External_CreateSpace(p))
                    sb.Append(.Template)
                End If
                If p.HasBook2 Then
                    .Reset()
                    .Replace("name", "Createspace(2)")
                    .Replace("url", CConfig.External_CreateSpace2(p))
                    sb.Append(.Template)
                End If
                If p.HasBook3 Then
                    .Reset()
                    .Replace("name", "Createspace(3)")
                    .Replace("url", CConfig.External_CreateSpace3(p))
                    sb.Append(.Template)
                End If
            Else
                If p.HasBook Then
                    .Replace("name", "Createspace")
                    .Replace("url", CConfig.External_CreateSpace(p))
                    sb.Append(.Template)
                End If
            End If

            Dim bb As CProductList = CProduct.Cache.Paperbacks.GetByCSBookIds(p.ProductCSBookId)
            If bb.Count > 0 Then
                p = bb(0)
                If Not String.IsNullOrEmpty(p.ProductAmazonId) Then
                    .Reset()
                    .Replace("name", "via Amazon")
                    .Replace("url", CConfig.External_Amazon(p.ProductAmazonId, p.ProductName))
                    sb.Append(.Template)
                End If
            End If
            bb = CProduct.Cache.Paperbacks.GetByCSBookIds(p.ProductCSBook2Id)
            If bb.Count > 0 Then
                p = bb(0)
                If Not String.IsNullOrEmpty(p.ProductAmazonId) Then
                    .Reset()
                    .Replace("name", "via Amazon")
                    .Replace("url", CConfig.External_Amazon(p.ProductAmazonId, p.ProductName))
                    sb.Append(.Template)
                End If
            End If
        End With

        With m_avContainer
            .Reset()
            .Replace("name", "Paperback")
            .Replace("items", sb.ToString)
            Return .Template
        End With
    End Function
    Private Function ManualLinks(ByVal p As CProduct) As String
        Dim sb As New StringBuilder

        With m_avItem
            .Reset()
            .Replace("name", HttpUtility.HtmlEncode(p.ProductName))
            .Replace("url", CConfig.WebsiteUrl_Product(p) & "#notes")
            sb.Append(.Template)

            If Not String.IsNullOrEmpty(p.ProductAmazonId) Then
                .Reset()
                .Replace("name", "via Amazon Kindle")
                .Replace("url", CConfig.External_Amazon(p.ProductAmazonId))
                sb.Append(.Template)
            End If
            If m_format = EFormat.HTML AndAlso p.ProductSmashwordsId > 0 Then
                .Reset()
                .Replace("name", "via Smashwords")
                .Replace("url", CConfig.External_Smashwords(p.ProductSmashwordsId))
                sb.Append(.Template)
            End If
        End With

        With m_avContainer
            .Reset()
            .Replace("name", "Manual")
            .Replace("items", sb.ToString)
            Return .Template
        End With
    End Function
    Private Function NotesLinks(ByVal p As CProduct) As String
        Dim sb As New StringBuilder
        With m_avItem
            For Each i As CProduct In p.Children
                If String.IsNullOrEmpty(i.ProductNotesAsPlainText) Then Continue For
                .Reset()
                If m_format = EFormat.SMASH Then
                    .Replace("name", "Notes: " & HttpUtility.HtmlEncode(i.ProductName))
                End If
                .Replace("name", HttpUtility.HtmlEncode(i.ProductName))
                If IsPagedHtml Then
                    .Replace("url", CSitemap.TranscriptWithPaging_(i, 100))
                Else
                    .Replace("url", "#n_" & i.ProductId)
                End If
                sb.Append(.Template)
            Next
        End With

        If sb.Length = 0 Then Return String.Empty

        With m_avContainer
            .Reset()
            .Replace("name", "Notes")
            .Replace("items", sb.ToString.Replace("target=""_blank""", String.Empty))
            Return .Template
        End With
    End Function


    Private Function Contents_Chapters(ByVal list As CProductList) As String
        Dim sb As New StringBuilder
        With m_contentsChapter
            For Each i As CProduct In list
                If i.ProductId = 706 Then Continue For
                If i.ProductTypeId_ = EProductType.Manual Then Continue For

                'Dim date_ As String = i.ProductCreated.ToString("d MMM yyyy")
                Dim name As String = i.ProductName
                If Not i.HasParent OrElse m_isInspRead Then name = String.Concat(1 + list.IndexOf(i), ". ", i.ProductName) 'i.ProductName 'String.Concat(date_, ": ", i.ProductName)

                .Reset()
                .Replace("productId", i.ProductId)
                If i.ProductSpeakerId <> ESpeaker.MikeConnell Then
                    .Replace("productName", HttpUtility.HtmlEncode(String.Concat(name, " (", i.SpeakerName, ")")))
                Else
                    .Replace("productName", HttpUtility.HtmlEncode(name))
                End If
                .Replace("productDescription", HttpUtility.HtmlEncode(i.ProductDescription).Replace(vbCrLf & vbCrLf, vbCrLf).Replace(vbCrLf, "<br/>"))
                If IsPagedHtml Then
                    .Replace("url", CSitemap.TranscriptWithPaging_(i))
                Else
                    .Replace("url", "#p_" & i.ProductId)
                End If
                .Replace("class", String.Empty)
                sb.AppendLine(.Template)

                If i.HasTranscriptChineseSimp Then
                    name = i.ProductNameChineseSimplified
                    If Not i.HasParent OrElse m_isInspRead Then name = String.Concat(1 + list.IndexOf(i), ". ", i.ProductNameChineseSimplified)

                    .Reset()
                    .Replace("productId", i.ProductId)
                    If i.ProductSpeakerId <> ESpeaker.MikeConnell Then
                        .Replace("productName", HttpUtility.HtmlEncode(String.Concat(name, " (", i.SpeakerName, ")")))
                    Else
                        .Replace("productName", HttpUtility.HtmlEncode(name))
                    End If
                    .Replace("productDescription", HttpUtility.HtmlEncode(i.ProductDescriptionChineseSimplified).Replace(vbCrLf, "<br/>"))
                    If IsPagedHtml Then
                        .Replace("url", CSitemap.TranscriptChineseSimplified_(i))
                    Else
                        .Replace("url", "#p_" & i.ProductId & "_simp")
                    End If
                    .Replace("class", "chinese")
                    sb.AppendLine(.Template)
                End If

                If i.HasTranscriptChineseTrad Then
                    name = i.ProductNameChineseTraditional
                    If Not i.HasParent OrElse m_isInspRead Then name = String.Concat(1 + list.IndexOf(i), ". ", i.ProductNameChineseTraditional)

                    .Reset()
                    .Replace("productId", i.ProductId)
                    If i.ProductSpeakerId <> ESpeaker.MikeConnell Then
                        .Replace("productName", HttpUtility.HtmlEncode(String.Concat(name, " (", i.SpeakerName, ")")))
                    Else
                        .Replace("productName", HttpUtility.HtmlEncode(name))
                    End If
                    .Replace("productDescription", HttpUtility.HtmlEncode(i.ProductDescriptionChineseTraditional).Replace(vbCrLf, "<br/>"))
                    If IsPagedHtml Then
                        .Replace("url", CSitemap.TranscriptChineseTraditional_(i))
                    Else
                        .Replace("url", "#p_" & i.ProductId & "_trad")
                    End If
                    .Replace("class", "chinese")
                    sb.AppendLine(.Template)
                End If
            Next

        End With
        Return sb.ToString
    End Function

    Private Function Contents_LinksToSets(ByVal list As CProductList) As String
        Dim sb As New StringBuilder
        With m_linkToSet
            For Each i As CProduct In list
                .Reset()
                .Replace("productId", i.ProductId)
                .Replace("productName", HttpUtility.HtmlEncode(String.Concat(1 + list.IndexOf(i), ". ", i.ProductName)))
                .Replace("description", i.Contents.Replace("Training Manual", "manual").Replace("Teaching Session", "session").Replace("Sunday Sermon", "sermon"))
                '.Replace("description", CUtilities.CountSummary(i.Children.HavingTranscripts, "sermon"))
                sb.AppendLine(.Template)
            Next

        End With
        If sb.Length > 0 Then sb.Insert(0, "<h1 style=""color:black"">Sermon Sets</h1>")
        Return sb.ToString
    End Function



    Private Function Transcriptions(ByVal list As CProductList) As String
        Dim sb As New StringBuilder

        'English
        For Each i As CProduct In list.BelongsTo
            If list.BelongsTo.Count > 1 Then sb.Append(Contents_Intro(i.Children, True))
            Transcriptions(sb, i.Children)
        Next
        If list.StandAlone.HavingTranscripts.Count > 1 Then
            sb.AppendLine("<h1>Sunday Sermons</h1>")
            Transcriptions(sb, list.StandAlone) '.HavingTranscripts)
        ElseIf list.StandAlone.Count = 1 Then
            Transcriptions(sb, list.StandAlone)
        End If

        'Chinese - Simp
        Dim simp As CProductList = list.HavingTranscriptsChineseSimp
        For Each i As CProduct In simp.BelongsTo
            If simp.BelongsTo.Count > 1 Then sb.Append(Contents_Intro(i.Children, True)) 'todo: language flag
            Transcriptions(sb, i.Children, True)
        Next
        If simp.StandAlone.HavingTranscripts.Count > 1 Then
            sb.AppendLine("<h1>Sunday Sermons</h1>")
            Transcriptions(sb, simp.StandAlone, True) '.HavingTranscripts)
        ElseIf simp.StandAlone.Count = 1 Then
            Transcriptions(sb, simp.StandAlone, True)
        End If

        'Chinese - Trad
        Dim trad As CProductList = list.HavingTranscriptsChineseTrad
        For Each i As CProduct In trad.BelongsTo
            If trad.BelongsTo.Count > 1 Then sb.Append(Contents_Intro(i.Children, True)) 'todo: language flag
            Transcriptions(sb, i.Children, False, True)
        Next
        If simp.StandAlone.HavingTranscripts.Count > 1 Then
            sb.AppendLine("<h1>Sunday Sermons</h1>")
            Transcriptions(sb, simp.StandAlone, False, True) '.HavingTranscripts)
        ElseIf simp.StandAlone.Count = 1 Then
            Transcriptions(sb, simp.StandAlone, False, True)
        End If

        Return sb.ToString
    End Function
    Private Sub Transcriptions(ByVal sb As StringBuilder, ByVal list As CProductList, Optional simp As Boolean = False, Optional trad As Boolean = False)
        With m_transcript
            For Each i As CProduct In list
                If i.ProductId = 706 Then Continue For 'double-up on the transcription
                If i.ProductTypeId_ = EProductType.Manual Then Continue For 'Not a transcription

                .Reset()
                If simp Then
                    .Replace("productId", i.ProductId & "_simp")
                ElseIf trad Then
                    .Replace("productId", i.ProductId & "_trad")
                End If
                .Replace("productId", i.ProductId)
                If list.Count = 1 Then
                    '.Replace("productName", String.Empty)
                    '.Replace("description", String.Empty)
                    .Replace("linkBackToContents", String.Empty)


                    Dim name As String = i.ProductName
                    If simp Then name = i.ProductNameChineseSimplified
                    If trad Then name = i.ProductNameChineseTraditionalOrSimplified
                    If i.ProductSpeakerId <> ESpeaker.MikeConnell AndAlso (m_isAllSermons OrElse m_isInspRead OrElse m_format = EFormat.HTML) Then
                        name = String.Concat(name, " (", i.SpeakerName, ")")
                    End If
                    .Replace("productName", HttpUtility.HtmlEncode(name))
                Else
                    Dim name As String = i.ProductName
                    If simp Then name = i.ProductNameChineseSimplified
                    If trad Then name = i.ProductNameChineseTraditionalOrSimplified
                    If i.ProductSpeakerId <> ESpeaker.MikeConnell AndAlso (m_isAllSermons OrElse m_isInspRead OrElse m_format = EFormat.HTML) Then
                        name = String.Concat(name, " (", i.SpeakerName, ")")
                    End If
                    If Not i.HasParent OrElse m_isInspRead Then name = String.Concat(1 + list.IndexOf(i), ". ", name)
                    .Replace("productName", HttpUtility.HtmlEncode(name))

                    m_backToContents.Reset()
                    If i.HasParent Then m_backToContents.ReplaceRaw("#contents", "#contents_" & i.ProductBelongsToProductId)
                    If simp Then m_backToContents.ReplaceRaw("Back to Top", "返回页首")
                    If trad Then m_backToContents.ReplaceRaw("Back to Top", "返回頁首")

                    .Replace("linkBackToContents", m_backToContents.Template)
                End If
                Dim desc As String = i.ProductDescription
                If simp Then desc = i.ProductDescriptionChineseSimplified
                If trad Then desc = i.ProductDescriptionChineseTraditionalOrSimplified
                .Replace("description", HttpUtility.HtmlEncode(desc).Replace(vbCrLf, "<br/>"))
                .Replace("dateString", i.DateString)
                .Replace("vimeo", IIf(i.ProductVimeoId > 0, i.VideoUrl_Vimeo, String.Empty))
                .Replace("youtube", IIf(Not String.IsNullOrEmpty(i.ProductYouTubeId), i.VideoUrl_YouTube, String.Empty))

                If i.HasTranscript Then
                    .Replace("googlead", m_googlead.Template)
                Else
                    .Replace("googlead", String.Empty)
                End If

                If i.HasImage AndAlso i.HasTranscript Then 'AndAlso Not i.HasParent Then
                    If (m_format = EFormat.SMASH OrElse m_format = EFormat.MOBI) And String.IsNullOrEmpty(i.ProductImage) Then .Replace("image", String.Empty)
                    m_image.Reset()
                    Dim name As String = i.ProductName
                    If simp Then name = i.ProductNameChineseSimplified
                    If trad Then name = i.ProductNameChineseTraditionalOrSimplified
                    m_image.Replace("name", name)
                    If (m_format = EFormat.MOBI OrElse m_format = EFormat.EPUB) Then
                        m_image.Replace("fileName", i.ProductImageOrParent.Replace(" ", String.Empty))
                    Else
                        m_image.Replace("fileName", i.ProductImageOrParent)
                    End If
                    m_image.Replace("url", CConfig.WebsiteUrl_ProductImage(i)) ' i.ProductImageOrParent)
                    .Replace("image", m_image.Template)
                Else
                    .Replace("image", String.Empty) 'TODO: Random speaker image (maybe better to do manually, as need to copy the file)
                End If

                .Replace("externalLinks", ExternalLinks(i, simp, trad))

                If simp Then
                    .Replace("text", CUtilities.ReplaceAll(i.ProductTranscriptionChineseSimplified, vbCrLf & vbCrLf, "</p>" & vbCrLf & "<p>"))
                ElseIf trad Then
                    .Replace("text", CUtilities.ReplaceAll(i.ProductTranscriptionChineseTraditional, vbCrLf & vbCrLf, "</p>" & vbCrLf & "<p>"))
                Else
                    .Replace("text", CUtilities.ReplaceAll(i.ProductTranscription, vbCrLf & vbCrLf, "</p>" & vbCrLf & "<p>"))

                End If

                If String.IsNullOrEmpty(i.ProductNotesAsPlainText) Then
                    .Replace("NotesAsText", String.Empty)
                Else
                    m_notesAsText.Reset()
                    m_notesAsText.Replace("notes", HttpUtility.HtmlEncode(i.ProductNotesAsPlainText).Replace(vbCrLf, "<br/>"))
                    m_notesAsText.Replace("productId", i.ProductId)
                    If i.Files.HasHtm Then
                        m_notesAsText.Replace("url", CConfig.DropboxUrl(i.Files.FirstHtm.FileName)) 'CConfig.WebsiteUrl_Product(i))
                    ElseIf i.Files.HasPdfOrWord Then
                        m_notesAsText.Replace("url", CConfig.DropboxUrl(i.Files.FirstPdfOrWord.FileName)) 'CConfig.WebsiteUrl_Product(i))
                    Else
                        m_notesAsText.Replace("url", CConfig.WebsiteUrl_Product(i))
                    End If

                    If i.HasParent Then
                        .Replace("NotesAsText", m_notesAsText.Template.Replace("#contents", "#contents_" & i.ProductBelongsToProductId))
                    Else
                        .Replace("NotesAsText", m_notesAsText.Template)
                    End If
                End If

                sb.AppendLine(.Template)
            Next
        End With
    End Sub

    Private Function ExternalLinks(ByVal sermon As CProduct, simp As Boolean, trad As Boolean) As String
        Dim sb As New StringBuilder
        If sermon.HasVideos Then
            If sermon.HasVideosOnBoth Then
                ExternalLink(sb, "YouTube", sermon.VideoUrl_YouTube, "Watch Video (on YouTube)")
                ExternalLink(sb, IIf(simp OrElse trad, "视频", "Vimeo"), sermon.VideoUrl_Vimeo, "Watch Video (on Vimeo)")
            Else
                ExternalLink(sb, IIf(simp OrElse trad, "视频", "Video"), sermon.VideoUrl, "Use the icon in the bottom-right corner to expand to full-screen")
            End If
        End If


        'If sermon.Files.HasHtm Then ExternalLink(sb, "Notes", CConfig.WebsiteUrl_Product(sermon) & "#notes", "Mike Connell's summary notes are also available for this Sermon")
        If Not String.IsNullOrEmpty(sermon.ProductNotesAsPlainText) Then
            InternalLink(sb, "Notes", "#n_" & sermon.ProductId, "Mike Connell's summary notes are also available for this Sermon")
        End If

        If sermon.HasAudio Then ExternalLink(sb, IIf(simp OrElse trad, "音频", "Audio"), CConfig.Mp3(sermon), "Download Audio Track (mp3)" & vbCrLf & "For best playback, use right-click + Save-As, to save to disk first (non-streaming download)")

        If sermon.HasBook2 OrElse sermon.HasBook3 Then
            If sermon.HasBook Then ExternalLink(sb, IIf(simp OrElse trad, "平装(1)", "Paperback(1)"), CConfig.External_CreateSpace(sermon), "A printed book of this sermon is also available")
            If sermon.HasBook2 Then ExternalLink(sb, IIf(simp OrElse trad, "平装(2)", "Paperback(2)"), CConfig.External_CreateSpace2(sermon), "A printed book of this sermon is also available")
            If sermon.HasBook3 Then ExternalLink(sb, IIf(simp OrElse trad, "平装(3)", "Paperback(3)"), CConfig.External_CreateSpace3(sermon), "A printed book of this sermon is also available")
        Else
            If sermon.HasBook Then ExternalLink(sb, IIf(simp OrElse trad, "平装", "Paperback"), CConfig.External_CreateSpace(sermon), "A printed book of this sermon is also available")
        End If

        If sermon.ProductImageScribeId = eScribe.Duncan Then
            ExternalLink(sb, "Photos", CConfig.WebsiteUrl_Product(sermon) & "#photos", "Duncan Brown photos available")
        End If

        'Facebook share
        If m_format = EFormat.HTML Then
            If sermon.HasParent Then
                ExternalLink(sb, "Share", CConfig.External_FacebookShare_Transcript(sermon.BelongsTo), "Share on Facebook")
            Else
                ExternalLink(sb, "Share", CConfig.External_FacebookShare_Transcript(sermon), "Share on Facebook")
            End If
        End If

        'Link to Amazon,ConferenceSets, or Transcripts
        If m_format = EFormat.MOBI Then
            ExternalLink(sb, "More", CConfig.External_Amazon, "More eBooks by Mike Connell")
            'ElseIf sermon.HasParent Then
            '    ExternalLink(sb, "More", CSitemap.ConferenceSets_(Nothing, 0, 0), "More Sermon Sets")
        Else
            If simp Then
                ExternalLink(sb, "网站", CSitemap.TranscriptChineseSimplified_(sermon), "More Transcripts")
            ElseIf trad Then
                ExternalLink(sb, "網站", CSitemap.TranscriptChineseTraditional_(sermon), "Website")
            Else
                ExternalLink(sb, "Website", CSitemap.TranscriptWithPaging_(sermon), "Website")
            End If
            'ExternalLink(sb, "More", CSitemap.Transcripts_(Nothing, 0), "More Sermons")
        End If

        ''Don't ask amazon users for donations
        'If m_format <> EFormat.MOBI Then
        '    If sermon.ProductSpeakerId = ESpeaker.ShaneWillard Then
        '        ExternalLink(sb, "Support", CConfig.External_ShaneWillardDonate, "Make a donation towards Shane Willard")
        '    Else
        '        ExternalLink(sb, "Support", CConfig.External_DonationsJeremy, "Make a donation towards sermon transcription, free eBooks and paperbacks")
        '    End If
        'End If

        ''Medium-Specific review links
        'If Not m_isAllSermons Then
        '    If m_format = EFormat.MOBI Then
        '        If sermon.ProductAmazonIdOrParent.Length > 0 Then ExternalLink(sb, "Review", CSitemap.External_ReviewAmazon(sermon), "Write a review for this sermon on Amazon")
        '    ElseIf m_format = EFormat.EPUB OrElse m_format = EFormat.SMASH Then
        '        If sermon.ProductSmashwordsId > 0 OrElse sermon.HasParent AndAlso sermon.BelongsTo.ProductSmashwordsId > 0 Then ExternalLink(sb, "Review", CSitemap.External_ReviewSmashwords(sermon), "Write a review for this sermon on Smashwords")
        '        'ElseIf m_format = EFormat.HTML Then
        '        'ExternalLink(sb, "Review Amazon", CSitemap.External_ReviewAmazon(sermon), "Write a review for this sermon on Amazon")
        '        'ExternalLink(sb, "Review Smashwords", CSitemap.External_ReviewSmashwords(sermon), "Write a review for this sermon on Smashwords")
        '    End If
        'End If

        If sermon.ProductSpeakerId <> ESpeaker.MikeConnell Then
            With sermon.Speaker
                If Not String.IsNullOrEmpty(.SpeakerWebsite) AndAlso (Not .SpeakerId = ESpeaker.ShaneWillard OrElse m_format = EFormat.MOBI) Then 'Shane has special donate link, except in mobi
                    ExternalLink(sb, .SpeakerName, "http://" & .SpeakerWebsite, .SpeakerName)
                End If
            End With
        End If

        If sb.Length > 0 AndAlso sb(0) = "|" Then sb.Remove(0, 1)
        Return sb.ToString
    End Function
    Private Sub ExternalLink(ByVal sb As StringBuilder, ByVal text As String, ByVal url As String, ByVal tooltip As String)
        sb.Append(ExternalLink(text, url, tooltip))
    End Sub
    Private Sub InternalLink(ByVal sb As StringBuilder, ByVal text As String, ByVal url As String, ByVal tooltip As String)
        sb.Append(ExternalLink(text, url, tooltip).Replace("target=""_blank""", String.Empty))
    End Sub
    Private Function ExternalLink(ByVal text As String, ByVal url As String, ByVal tooltip As String) As String
        With m_externalLink
            .Reset()
            .Replace("text", text)
            .Replace("url", url)
            .Replace("tooltip", tooltip)
            Return .Template
        End With
    End Function
#End Region

#Region "Shared"
    Public Shared Function TitleFor(ByVal list As List(Of Integer)) As String
        Return TitleFor(CProduct.Cache.GetByIds(list))
    End Function
    Public Shared Function TitleFor(ByVal list As CProductList) As String
        Dim title As String = String.Concat(list(list.Count - 1).DateString, " - ", list(0).DateString).Replace("Sun ", "").Replace(" PM", "pm").Replace(" AM", "am").Replace(" 201", "'1")
        If list.Count = 1 Then title = list(0).ProductName
        Return title
    End Function
#End Region

End Class
